#region Copyright Notices
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
// 
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#endregion

using System;

namespace Yarr
{
    /// <summary>
    /// Identifies the default pacakge for the symbols in an imported class
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=false)]
    public sealed class PackageAttribute : Attribute
    {
        #region Private members
        private string packageName;
        #endregion

        #region Public properties
        public string PackageName
        {
            get { return packageName; }
        }
        #endregion

        #region Constructors
        public PackageAttribute(string package)
        {
            this.packageName = package;
        }
        #endregion
    }

    /// <summary>
    /// Base class function and eval attributes
    /// </summary>
    public abstract class YarrBaseAttribute : Attribute
    {
        public string binding;
        public string signature;

        /// <summary>
        /// Construct an YarrBaseAttribute
        /// </summary>
        /// <param name="binding">A semi-colon separated list of names of the symbols to be bound to this method</param>
        protected YarrBaseAttribute(string binding) 
        {
            if (String.IsNullOrEmpty(binding))
                this.binding = null;
            else
                this.binding = binding;
        }

        /// <summary>
        /// Construct an YarrBaseAttribute
        /// </summary>
        /// <param name="binding">A semi-colon separated list of names of the symbols to be bound to this method</param>
        /// <param name="signature">A string representation of the function signature</param>
        protected YarrBaseAttribute(string binding, string signature)
            : this(binding)
        {
            this.signature = signature;
        }

    }

    /// <summary>
    /// Baase class for reader macros
    /// </summary>
    public abstract class YarrBaseReaderAttribute : Attribute
    {
        private Char binding;
        /// <summary>
        /// The character to bind
        /// </summary>
        public Char Binding { get { return binding; } }

        /// <summary>
        /// Create an YarrBaseReaderAttribute
        /// </summary>
        /// <param name="binding">The character to bind</param>
        protected YarrBaseReaderAttribute(Char binding)
        {
            this.binding = binding;
        }
    }

    /// <summary>
    /// Marks a method as being an Yarr function
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=false)]
    public sealed class FunctionAttribute : YarrBaseAttribute
    {
        /// <summary>
        /// Construct a FunctionAttribute
        /// </summary>
        /// <param name="binding">A semi-colon separated list of names of the symbols to be bound to this method</param>
        public FunctionAttribute (string binding) : base(binding) { }

        /// <summary>
        /// Construct a FunctionAttribute with a function signature
        /// </summary>
        /// <param name="binding">A semi-colon separated list of names of the symbols to be bound to this method</param>
        /// <param name="signature">A string representation of the function signature</param>
        public FunctionAttribute(string binding, string signature) : base(binding, signature) { }
    }

    /// <summary>
    /// Marks a method as beign an Yarr special form
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=false)]
    public sealed class SpecialFormAttribute : YarrBaseAttribute
    {
        /// <summary>
        /// Construct a SpecialFormAttribute
        /// </summary>
        /// <param name="binding">The name of the symbol to be bound to this method</param>
        public SpecialFormAttribute (string binding) : base(binding) { }

        /// <summary>
        /// Construct a SpecialFormAttribute with a function signature
        /// </summary>
        /// <param name="binding">A semi-colon separated list of names of the symbols to be bound to this method</param>
        /// <param name="signature">A string representation of the function signature</param>
        public SpecialFormAttribute(string binding, string signature) : base(binding, signature) { }
    }

    /// <summary>
    /// Marks a field as Yarr code to evaluate
    /// </summary>
    [AttributeUsage(AttributeTargets.Field, AllowMultiple=false, Inherited=false)]
    public sealed class EvalAttribute : YarrBaseAttribute
    {
        /// <summary>
        /// Construct an EvalAttribute
        /// </summary>
        public EvalAttribute () : base(null) { }

        /// <summary>
        /// Construct an EvalAttribute
        /// </summary>
        /// <param name="binding">A semi-colon separated list of names of the symbols to be bound to the result</param>
        public EvalAttribute(string binding) : base(binding) { }
}

    /// <summary>
    /// Marks a method as being a setf method
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=false)]
    public sealed class SetfAttribute : YarrBaseAttribute
    {
        /// <summary>
        /// Construct a SetfAttribute
        /// </summary>
        /// <param name="binding">A semi-colon separated list of names of the symbols to be bound to this method</param>
        public SetfAttribute(string binding) : base(binding) { }

        /// <summary>
        /// Construct a SetfAttribute with a particular signature
        /// </summary>
        /// <param name="binding">A semi-colon separated list of names of the symbols to be bound to this method</param>
        /// <param name="signature">A string representation of the function signature</param>
        public SetfAttribute(string binding, string signature) : base(binding, signature) { }
    }

    /// <summary>
    /// Marks a method as being a reader macro
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple=true, Inherited=false)]
    public sealed class ReaderMacroAttribute : YarrBaseReaderAttribute
    {
        /// <summary>
        /// Constructs a ReaderMacroAttribute
        /// </summary>
        /// <param name="binding">The character to be bound to this reader macro</param>
        public ReaderMacroAttribute (Char binding) : base(binding) { }
    }

    /// <summary>
    /// Marks a method as being a dispatch reader macro
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple=true, Inherited=false)]
    public sealed class DispatchReaderMacroAttribute : YarrBaseReaderAttribute
    {
        private Char subChar;
        /// <summary>
        /// The character to dispatch
        /// </summary>
        public Char SubChar { get { return subChar; } }

        /// <summary>
        /// Constructs a DispatchReaderMacroAttribute
        /// </summary>
        /// <param name="binding">The character to be bound to a dispatch reader</param>
        /// <param name="subBinding">The character to be bound to this reader macro</param>
        public DispatchReaderMacroAttribute (Char binding, Char subBinding) : base(binding) 
        {
            this.subChar = subBinding;
        }
    }
}
